//
//  CTVChannelCollectionParser.m
//  Channltv
//
//  Created by Bruno Keymolen on 03/09/07.
//  Copyright 2007 channl.tv. All rights reserved.
//

#import "CTVChannelCollectionParser.h"
#import "CTVChannel.h";
#import "CTVCache.h"


@implementation CTVChannelCollectionParser

-(id)init{
	[super init];
	
	
	m_channels = [[NSMutableArray alloc] init]; //CTVChannel collection
	
	return self;
}

-(void)dealloc{
	if(m_channelCollectionIconUrlString)
		[m_channelCollectionIconUrlString release];
	if(m_channelCollectionName)
		[m_channelCollectionName release];
		
	[self _releaseChannels];
	[m_channels release];
	
	[super dealloc];
}

-(NSArray*)channels{
	return m_channels;
}

-(NSString*)channelCollectionName{
	return m_channelCollectionName;
}

-(NSString*)channelCollectionIconUrlString{
	return m_channelCollectionIconUrlString;
}


-(int)parseFromPath:(NSString*)path{
	int ret = 0;
	
	//Read the data from the file
	NSData* data = [NSData dataWithContentsOfFile:path];
	if(data == nil){
		NSLog(@"Error, CTVChannelCollectionParser. Could not read data from file %@", path); 
		ret -1;
	}else{
		ret = [self parseFromData:data];
	}
	
	return ret;
}


-(int)parseFromData:(NSData*)data{
	int ret = 0;
	[self _releaseChannels]; //empty the eventually previous collection

	CTVChannel* channel;
	NSXMLDocument* xmlDoc;

	NSError *err=nil;	
	xmlDoc = [[NSXMLDocument alloc] initWithData:data options:(NSXMLNodePreserveWhitespace|NSXMLNodePreserveCDATA) error:&err]; 
	
	if(xmlDoc == nil){
		ret -1;
		NSLog(@"Error, CTVChannelCollectionParser. Could not parse"); 		
	}else{
		int channelCnt, totalChannels, childt, childcnt;
		NSXMLNode* channelNode;
		NSXMLNode* aNode; 

		//Channels collection info
		if(m_channelCollectionName)
			[m_channelCollectionName release];
		NSArray* channelInfo = [xmlDoc nodesForXPath:@"//rss/channel/title" error:&err];
		if([channelInfo count] <= 0){
			m_channelCollectionName = @"Group Name Undefined";
		}else{				
			aNode = [channelInfo objectAtIndex:0];
			m_channelCollectionName = [NSString stringWithString:[aNode stringValue]];
		}
		[m_channelCollectionName retain];
		
		
		//Channels
		NSArray* channelCollection = [xmlDoc nodesForXPath:@"//rss/channel/item" error:&err];
		
		totalChannels = [channelCollection count];
		
		for(channelCnt=0;channelCnt<totalChannels;channelCnt++){
			channelNode = [channelCollection objectAtIndex:channelCnt];
			channel = [[CTVChannel alloc] initWithRootChannelPointer:nil]; //ALLOC
			[m_channels addObject:channel];
			
			childcnt = [channelNode childCount];
			for (childt=0;childt<childcnt;childt++) {
				aNode = [channelNode childAtIndex:childt];
				if([aNode kind] == NSXMLElementKind) {
					NSString* sVal = [NSString stringWithString:[aNode stringValue]];
					NSString* oVal = [NSString stringWithString:[aNode name]];
					if (sVal != nil) {
						if( [oVal caseInsensitiveCompare:@"title"] == NSOrderedSame){
							//Title
							[channel setName:sVal]; //copy the title to the memory slot for this program
						}else if( [oVal caseInsensitiveCompare:@"description"] == NSOrderedSame){
							//Nothing
						}else if( [oVal caseInsensitiveCompare:@"link"] == NSOrderedSame){
							//ClipsInChannel URL
							[channel setUrl:sVal]; 						
						}else if( [oVal caseInsensitiveCompare:@"guid"] == NSOrderedSame){
							//GUID
							[channel setChannelId:[CTVCache getHashString:sVal]]; 
						}else if( [oVal caseInsensitiveCompare:@"media:thumbnail"] == NSOrderedSame){
							//Thumnnail
							NSXMLElement* xmlElement = (NSXMLElement*)aNode; //NSXMLElement is derived from NSXMLNode
							aNode = [xmlElement attributeForName:@"url"];
							sVal = [aNode stringValue];
							[channel setThumbUrl:sVal];
						}
					}				
				}
			}
			//Channel data structs are filled, do some additional tasks
			if([channel thumbUrl] == nil || [[channel thumbUrl] isEmpty]){
				[channel setThumbUrl:[[NSBundle bundleForClass: [self class]] pathForResource:@"logo" ofType: @"png"]];
			}
			//Channel watchpoint (if exist)
//			[[CTVCache GetInstance] loadWatchPoint:channel];
//NSLog(@"Channel watchpoint offset=%f, clip=%@<", [[channel watchPoint] offset], [[channel watchPoint] clipID] );			
		}
		
	}

	
	[xmlDoc release];
	
	return ret;
}



//Private
-(void)_releaseChannels{
	CTVChannel* channel;
	NSEnumerator* enumerator = [m_channels objectEnumerator];
	while (channel = [enumerator nextObject]) {
		[channel release]; //because we allocated (retain must be used outside this class if the channels should stay in memory)
	}
	[m_channels removeAllObjects];
}

@end

